Completed
Push — master ( e01337...7c5d19 )
by
unknown
02:22
created

save.js ➔ saveHtml   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
c 1
b 0
f 0
nc 2
dl 0
loc 7
rs 9.4285
nop 2
1
import fse from 'fs-extra'
2
import extend from 'extend'
3
import mkdirp from 'mkdirp'
4
import xss from 'xss'
5
import {Promise} from 'es6-promise'
6
import path from 'path'
7
8
import {
9
  cmsOperations,
10
  cmsData,
11
  config,
12
  Page,
13
  cmsTemplates,
14
  abeExtend,
15
  coreUtils
16
} from '../../'
17
18
export function checkRequired(text, json) {
19
  var regAbe = /{{abe[\S\s].*?key=['|"]([\S\s].*?['|"| ]}})/g
20
  var matches = text.match(regAbe)
21
  var requiredValue = 0
22
  var complete = 0
23
  if(typeof matches !== 'undefined' && matches !== null){
24
    Array.prototype.forEach.call(matches, (match) => {
25
      if(typeof match !== 'undefined' && match !== null) {
26
        
27
        var keyAttr = cmsData.regex.getAttr(match, 'key')
28
        var requiredAttr = cmsData.regex.getAttr(match, 'required')
29
        if(requiredAttr === 'true') {
30
          requiredValue++
31
32
          var minAttr = cmsData.regex.getAttr(match, 'min-length')
33
          minAttr = (minAttr !== '') ? minAttr : 0
34
35
          if(typeof json[keyAttr] !== 'undefined' && json[keyAttr] !== null && json[keyAttr] !== '') {
36
            if(minAttr > 0) {
37
              if(json[keyAttr].length >= minAttr) {
38
                complete++
39
              }
40
            }else {
41
              complete++
42
            }
43
          }
44
        }
45
      }
46
    })
47
  }
48
49
  return Math.round((requiredValue > 0) ? complete * 100 / requiredValue : 100)
50
}
51
52
export function save(url, tplPath, json = null, text = '', type = '', previousSave = null, realType = 'draft', publishAll = false) {
53
  url = coreUtils.slug.clean(url)
54
55
  var p = new Promise((resolve) => {
56
    var isRejectedDoc = false
57
    if(type === 'reject'){
58
      isRejectedDoc = true
59
      url = abeExtend.hooks.instance.trigger('beforeReject', url)
60
      type = 'draft'
61
      realType = 'draft'
62
      url = abeExtend.hooks.instance.trigger('afterReject', url)
63
    }
64
    var tplUrl = cmsData.file.fromUrl(url)
65
    type = type || 'draft'
66
    var pathIso = dateIso(tplUrl, type)
67
    if(typeof previousSave !== 'undefined' && previousSave !== null){
68
      pathIso.jsonPath = path.join(config.root, previousSave.jsonPath.replace(config.root, '')).replace(/-abe-d/, `-abe-${realType[0]}`)
69
      pathIso.htmlPath = path.join(config.root, previousSave.htmlPath.replace(config.root, '')).replace(/-abe-d/, `-abe-${realType[0]}`)
70
    }
71
72
    if (tplPath.indexOf('.') > -1) {
73
      tplPath = tplPath.replace(/\..+$/, '')
74
    }
75
    var tpl = tplPath.replace(config.root, '')
76
77
    var fullTpl = path.join(config.root, config.templates.url, tpl) + '.' + config.files.templates.extension
78
79
    if(typeof json === 'undefined' || json === null) {
80
      json = cmsData.file.get(tplUrl.json.path)
81
    }
82
83
    var ext = {
84
      template: tpl.replace(/^\/+/, ''),
85
      link: tplUrl.publish.link,
86
      complete: 0,
87
      type: type
88
    }
89
    let meta = config.meta.name
90
    json[meta] = extend(json[meta], ext)
91
    var date = cmsData.fileAttr.get(pathIso.jsonPath).d
92
93
    if (publishAll) {
94
      if(typeof json[meta].publish !== 'undefined' && json[meta].publish !== null) {
95
        date = json[meta].publish.date
96
      }
97
    }else {
98
      if(typeof date === 'undefined' || date === null || date === '') {
99
        date = new Date()
100
      }else {
101
        date = new Date(date)
102
      }
103
    }
104
105
    cmsData.metas.add(tpl, json, type, {}, date, realType)
106
107
    if(typeof text === 'undefined' || text === null || text === '') {
108
      text = cmsTemplates.template.getTemplate(fullTpl)
109
    }
110
111
    cmsData.source.getDataList(path.dirname(tplUrl.publish.link), text, json)
112
        .then(() => {
113
114
          json = abeExtend.hooks.instance.trigger('afterGetDataListOnSave', json)
115
          for(var prop in json){
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
116
            if(typeof json[prop] === 'object' && Array.isArray(json[prop]) && json[prop].length === 1){
117
              var valuesAreEmpty = true
118
              json[prop].forEach(function (element) {
119
                for(var p in element) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
120
                  if(element[p] !== ''){
121
                    valuesAreEmpty = false
122
                  }
123
                }
124
              })
125
              if(valuesAreEmpty){
126
                delete json[prop]
127
              }
128
            }
129
          }
130
131
          var obj = {
132
            publishAll:publishAll,
133
            type:type,
134
            template:{
135
              path: fullTpl
136
            },
137
            html: {
138
              path:pathIso.htmlPath
139
            },
140
            json: {
141
              content: json,
142
              path: pathIso.jsonPath
143
            }
144
          }
145
146
          obj = abeExtend.hooks.instance.trigger('beforeSave', obj)
147
148
          obj.json.content[meta].complete = checkRequired(text, obj.json.content)
149
150
          var res = saveJsonAndHtml(tpl.replace(/^\/+/, ''), obj, text)
151
          if (isRejectedDoc) {
152
            res.reject = cmsData.fileAttr.delete(url).replace(path.join(config.root, config.draft.url), '')
153
          }
154
          
155
          abeExtend.hooks.instance.trigger('afterSave', obj)
156
          
157
          cmsTemplates.assets.copy()
158
159
          resolve(res)
160
        }).catch(function(e) {
161
          console.error('Save.js', e)
162
        })
163
  })
164
165
  return p
166
}
167
168
export function saveJsonAndHtml(templateId, obj, html) {
169
  var page = new Page(templateId, html, obj.json.content, true)
170
171
  if (obj.json.content.abe_meta.status === 'publish') {
172
    saveHtml(obj.html.path, page.html)
173
  }
174
  saveJson(obj.json.path, obj.json.content)
175
176
  return {
177
    json: obj.json.content,
178
    jsonPath: obj.json.path,
179
    html: page.html,
180
    htmlPath: obj.html.path
181
  }
182
}
183
184
export function saveJson(url, json) {
185
  mkdirp.sync(path.dirname(url))
186
187
  if(typeof json.abe_source !== 'undefined' && json.abe_source !== null) {
188
    delete json.abe_source
189
  }
190
191
  var eachRecursive = function (obj) {
192
    for (var k in obj) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
193
      if (typeof obj[k] === 'object' && obj[k] !== null){
194
        eachRecursive(obj[k])
195
      } else if (typeof obj[k] !== 'undefined' && obj[k] !== null){
196
        obj[k] = xss(obj[k].toString().replace(/"/g, '"'), { 'whiteList': config.htmlWhiteList })
197
      }
198
    }
199
  }
200
201
  eachRecursive(json)
202
203
  fse.writeJsonSync(url, json, {
204
    space: 2,
205
    encoding: 'utf-8'
206
  })
207
  return true
208
}
209
210
export function saveHtml(url, html) {
211
  mkdirp.sync(path.dirname(url))
212
  if(cmsData.fileAttr.test(url) && cmsData.fileAttr.get(url).s !== 'd'){
213
    cmsOperations.remove.olderRevisionByType(cmsData.fileAttr.delete(url), cmsData.fileAttr.get(url).s)
214
  }
215
  fse.writeFileSync(url, html)
216
}
217
218
export function dateIso(tplUrl, type = null) {
219
  var newDateISO
220
  var dateISO
221
  var saveJsonFile = tplUrl.json.path
0 ignored issues
show
Unused Code introduced by
The assignment to variable saveJsonFile seems to be never used. Consider removing it.
Loading history...
222
  var saveFile = tplUrl['draft'].path
0 ignored issues
show
Unused Code introduced by
The assignment to variable saveFile seems to be never used. Consider removing it.
Loading history...
223
  
224
  switch(type) {
225
  case 'draft':
226
    newDateISO = cmsData.revision.removeStatusAndDateFromFileName((new Date().toISOString()))
227
    dateISO = 'd' + newDateISO
228
    break
229
  case 'publish':
230
    saveJsonFile = tplUrl.publish.json
231
    saveFile = tplUrl.publish.path
232
    break
233
  default:
234
    newDateISO = cmsData.revision.removeStatusAndDateFromFileName((new Date().toISOString()))
235
    dateISO = type[0] + newDateISO
236
    break
237
  }
238
239
  if(dateISO) {
240
    saveJsonFile = cmsData.fileAttr.add(saveJsonFile, dateISO)
241
    saveFile = cmsData.fileAttr.add(saveFile, dateISO)
242
  }
243
244
  return {
245
    jsonPath: saveJsonFile,
246
    htmlPath: saveFile
247
  }
248
}